use crate::components::component::{App, ScrollTrait};
use crate::components::enums::{
    AppMode, ConnectionStatus, HttpMethod, HttpRequestContentType, HttpResponseContentType,
    NetworkCommand, NetworkEvent, PromptLevel, ProtocolType,
};
use crate::rpc::http::{HttpError, execute_request};
use crate::util;
use arboard::Clipboard;
use ratatui::style::Color;
use std::fmt::{self, Display};

impl Default for App {
    fn default() -> Self {
        Self {
            // 状态机：当前状态
            mode: AppMode::Normal,
            // tokio的网络连接
            connection_status: ConnectionStatus::default(),
            cmd_tx: None,
            event_rx: None,
            event_tx: None,
            task_handle: None,
            // 协议。控制两套不同ui
            protocol: ProtocolType::Tcp,
            // 以下几个属性是tcp/udp/http共用的属性
            server_addr: "127.0.0.1:8080".to_string(),
            logs: "Ready to connect...".to_string(),
            current_input: String::from(""),
            scroll_position: 0,
            // tcp/udp 属性
            request_data: String::new(),
            received_data: String::new(),
            // http 属性
            request_http_body: String::from(""),
            request_http_headers: vec![],
            request_http_params: vec![],
            http_method: HttpMethod::Get,
            response_http_body: String::from(""),
            response_http_headers: vec![],
            response_http_cookies: vec![],
            response_http_status_code: 0,
            request_content_type: HttpRequestContentType::Json,
            response_content_type: HttpResponseContentType::Json,
            // 终止程序标志位
            quit_tag: false,
        }
    }
}

// 手动为 App 实现 Clone, 因为tokio的几个字段没有实现clone，需要手动处理
impl Clone for App {
    fn clone(&self) -> Self {
        Self {
            // 只克隆可以安全复制的字段
            event_tx: self.event_tx.clone(),
            cmd_tx: self.cmd_tx.clone(),

            // 下面这些字段在派发任务时不需要，设为 None
            event_rx: None,
            task_handle: None,

            // 其他所有数据字段正常克隆
            connection_status: self.connection_status,
            protocol: self.protocol,
            server_addr: self.server_addr.clone(),
            logs: self.logs.clone(),
            scroll_position: self.scroll_position,
            mode: self.mode,
            current_input: self.current_input.clone(),
            request_data: self.request_data.clone(),
            received_data: self.received_data.clone(),
            request_http_headers: self.request_http_headers.clone(),
            request_http_params: self.request_http_params.clone(),
            request_http_body: self.request_http_body.clone(),
            http_method: self.http_method,
            request_content_type: self.request_content_type,
            response_http_status_code: self.response_http_status_code,
            response_http_body: self.response_http_body.clone(),
            response_http_headers: self.response_http_headers.clone(),
            response_http_cookies: self.response_http_cookies.clone(),
            response_content_type: self.response_content_type,
            quit_tag: self.quit_tag,
        }
    }
}

impl App {
    pub fn is_http_protocol(&self) -> bool {
        self.protocol == ProtocolType::Http
    }
    
    // 更新当前mode
    pub fn update_mode(&mut self, mode: AppMode) {
        self.mode = mode;
    }

    // 恢复mode到普通模式
    pub fn reset_mode(&mut self) {
        self.mode = AppMode::Normal
    }

    // 提交当前输入到 Headers，要匹配 key:value 的模式
    pub fn submit_header(&mut self) {
        if let Some((key, value)) = self.current_input.split_once(':') {
            self.request_http_headers
                .push((key.trim().to_string(), value.trim().to_string()));
        }
        self.current_input.clear();
    }

    // 提交当前输入到 Parameters，要匹配 key=value 的模式
    pub fn submit_param(&mut self) {
        if let Some((key, value)) = self.current_input.split_once('=') {
            self.request_http_params
                .push((key.trim().to_string(), value.trim().to_string()));
        }
        self.current_input.clear();
    }

    // 切换协议的逻辑
    pub fn switch_protocol(&mut self) {
        self.protocol = match self.protocol {
            ProtocolType::Tcp | ProtocolType::Udp => ProtocolType::Http,
            ProtocolType::Http => ProtocolType::Tcp,
        };
    }

    // 在tcp_udp.ui里切换tcp/udp
    pub fn cycle_protocol(&mut self) {
        self.protocol = match self.protocol {
            ProtocolType::Tcp => ProtocolType::Udp,
            ProtocolType::Udp => ProtocolType::Tcp,
            _ => unreachable!(),
        }
    }

    // 监听粘贴事件以后，把粘贴的内容赋值给current_input
    pub fn paste(&mut self, data: &str) {
        if self.mode.is_editing() {
            // 只有编辑模式下允许粘贴
            self.current_input.push_str(data);
        }
    }

    // 循环切换 HTTP Method 的方法
    pub fn cycle_http_method(&mut self) {
        self.http_method = self.http_method.next();
    }

    //  循环切换 Request Content-Type 的方法
    pub fn cycle_request_content_type(&mut self) {
        self.request_content_type = self.request_content_type.next();
    }

    // 通过这个标志来控制程序是否退出
    pub fn set_quit(&mut self) {
        self.quit_tag = true
    }

    // 判断tcp 是否未连接
    pub fn is_not_connected(&self) -> bool {
        self.connection_status != ConnectionStatus::Connected
    }

    // 判断tcp 是否已连接
    pub fn connected(&self) -> bool {
        self.connection_status == ConnectionStatus::Connected
    }

    // 如果status.code == 0，表示还没有发送请求
    pub fn not_request_yet(&self) -> bool {
        self.response_http_status_code == 0
    }

    // 清除所有输入和状态
    pub fn clear(&mut self) {
        self.current_input.clear();
        self.http_method = HttpMethod::Get;
        self.request_content_type = HttpRequestContentType::Json;
        self.request_http_body = String::new();
        self.request_http_params = vec![];
        self.request_data = String::new();
        self.request_http_headers = vec![];
        self.scroll_position = 0;
        self.response_http_status_code = 0;
        self.response_http_body.clear();
        self.response_http_headers.clear();
        self.response_http_status_code = 0;
        self.response_http_body.clear();
        self.response_http_headers.clear();
        self.scroll_position = 0;
        self.received_data = String::new();
    }

    // send_http_request
    pub fn send_http_request(&mut self) {
        self.response_http_status_code = 0;
        self.response_http_body.clear();
        self.response_http_headers.clear();
        self.scroll_position = 0;
        self.logs = "Sending HTTP request...".to_string();

        // 如果 event_tx 不存在，则创建一套新的通道
        if self.event_tx.is_none() {
            let (event_tx, event_rx) = tokio::sync::mpsc::unbounded_channel();
            self.event_tx = Some(event_tx);
            self.event_rx = Some(event_rx);
        }

        // 克隆一份 App 状态和事件发送端，用于传递给异步任务
        let app_state = self.clone();
        let event_tx = self.event_tx.clone().unwrap(); // clone() 是安全的

        tokio::spawn(async move {
            let result = match execute_request(&app_state).await {
                Ok(response) => Ok(Box::new(response)),
                Err(e) => {
                    let error_message = match e {
                        HttpError::Request(err) => format!("Request Error: {err}"),
                        HttpError::InvalidHeader(err_str) => {
                            format!("Header Error: {err_str}")
                        }
                    };
                    Err(error_message)
                }
            };
            // 【关键】使用正确的 event_tx 发送正确的 NetworkEvent
            let _ = event_tx.send(NetworkEvent::HttpResponse(result));
        });
    }

    pub fn copy_http_response_cookies(&mut self) {
        let cookies_to_copy = match self.protocol {
            ProtocolType::Http => {
                if self.not_request_yet() || self.response_http_cookies.is_empty() {
                    self.logs = " Log: No response cookies to copy".to_string();
                    return;
                }
                self.response_http_cookies.clone()
            }
            _ => {
                vec![]
            }
        };
        if cookies_to_copy.is_empty() {
            self.logs = "Log: Response headers is empty, nothing to copy.".to_string();
            return;
        }
        self.logs = "Log: Attempting to access clipboard...".to_string();
        let cookies_to_string: String = cookies_to_copy.iter().map(|s| s.to_string()).collect::<Vec<String>>().join("\n");
        self.copy_to_clipboard("Response-Headers".into(),cookies_to_string);
    }

    /// 复制response-headers到剪贴板
    pub fn copy_http_response_headers(&mut self) {
        let headers_to_copy: Vec<(String, String)> = match self.protocol {
            ProtocolType::Http => {
                if self.not_request_yet() || self.response_http_headers.is_empty() {
                    self.logs = " Log: No response headers to copy".to_string();
                    return;
                }
                self.response_http_headers.clone()
            }
            _ => {
                vec![]
            }
        };
        if headers_to_copy.is_empty() {
            self.logs = "Log: Response headers is empty, nothing to copy.".to_string();
            return;
        }
        self.logs = "Log: Attempting to access clipboard...".to_string();
        let headers_to_string = headers_to_copy.iter().map(|(k,v)| format!("{k}:{v}")).collect::<Vec<String>>().join("\n");
        self.copy_to_clipboard("Response-Headers".into(),headers_to_string);
    }

    /// 复制response-body到剪贴板
    pub fn copy_response_body(&mut self) {
        let content_to_copy = match self.protocol {
            ProtocolType::Http => {
                if self.not_request_yet() || self.response_http_body.is_empty() {
                    self.logs = "Log: No response to copy.".to_string();
                    return;
                }
                self.response_http_body.clone()
            }
            ProtocolType::Tcp | ProtocolType::Udp => {
                if self.received_data.is_empty() {
                    self.logs = "Log: No response to copy.".to_string();
                    return;
                }
                self.received_data.clone()
            }
        };

        if content_to_copy.is_empty() {
            self.logs = "Log: Response content is empty, nothing to copy.".to_string();
            return;
        }
        self.logs = "Log: Attempting to access clipboard...".to_string();
        self.copy_to_clipboard("Response-Body".into(),content_to_copy)
    }

    fn copy_to_clipboard(&mut self, copy_tag: String, content_to_copy: String) {
        self.logs = "Log: Attempting to access clipboard...".to_string();
        match Clipboard::new() {
            Ok(mut clipboard) => match clipboard.set_text(content_to_copy) {
                Ok(_) => {
                    if copy_tag.is_empty() {
                        self.logs = "Log: ✔ copied to clipboard!".to_string();
                    } else {
                        self.logs = format!("Log: ✔ {copy_tag} copied to clipboard!");
                    }
                }
                Err(e) => {
                    if copy_tag.is_empty() {
                        self.logs = format!("Error: ❌ failed to copy to clipboard: {e}");
                    } else {
                        self.logs =
                            format!("Error: ❌ {copy_tag} failed to copy to clipboard: {e}");
                    }
                }
            },
            // 修改：移除了关于 xclip 的提示，因为不再需要它了
            Err(e) => {
                self.logs = format!("Error: ❌ Failed to initialize clipboard: {e}");
            }
        }
    }

    pub fn connect(&mut self) {
        self.disconnect();
        if matches!(self.protocol, ProtocolType::Http) {
            self.logs = "Error: Connect action is not for HTTP protocol.".into();
            return;
        }

        // 创建一套完整的通道
        let (cmd_tx, cmd_rx) = tokio::sync::mpsc::unbounded_channel();
        let (event_tx, event_rx) = tokio::sync::mpsc::unbounded_channel();

        // 【关键】存储所有需要的通道端点
        self.cmd_tx = Some(cmd_tx.clone());
        self.event_tx = Some(event_tx.clone());
        self.event_rx = Some(event_rx);

        let task = match self.protocol {
            ProtocolType::Tcp => tokio::spawn(crate::rpc::tcp::tcp_task(cmd_rx, event_tx)),
            ProtocolType::Udp => tokio::spawn(crate::rpc::udp::udp_task(cmd_rx, event_tx)),
            _ => unreachable!(),
        };
        self.task_handle = Some(task);
        self.logs = format!(
            "Connecting to {} over {}...",
            self.server_addr, self.protocol
        );
        self.connection_status = ConnectionStatus::Connecting;
        let _ = cmd_tx.send(NetworkCommand::Connect(self.server_addr.clone()));
    }

    /// 断开连接，这会中止正在运行的网络任务
    pub fn disconnect(&mut self) {
        if let Some(handle) = self.task_handle.take() {
            handle.abort();
            self.logs = "Connection task aborted.".into();
        }
        self.connection_status = ConnectionStatus::Disconnected;
        self.cmd_tx = None;
        self.event_tx = None;
        self.event_rx = None;
    }

    /// 发送 TCP/UDP 数据
    pub fn send_tcp_udp_data(&mut self) {
        if self.connection_status == ConnectionStatus::Connected {
            if let Some(tx) = &self.cmd_tx {
                let data_to_send = self.request_data.clone();
                if tx
                    .send(NetworkCommand::Send(data_to_send.as_bytes().to_vec()))
                    .is_ok()
                {
                    self.logs = format!("Sent: {data_to_send}");
                } else {
                    self.logs = "Error: Failed to send command to network task.".into();
                }
            }
        } else {
            self.logs = "Error: Not connected.".into();
        }
    }

    pub fn process_network_events(&mut self) {
        if let Some(rx) = &mut self.event_rx {
            while let Ok(event) = rx.try_recv() {
                match event {
                    NetworkEvent::Connected => {
                        self.connection_status = ConnectionStatus::Connected;
                        self.logs = "✔ Connected successfully!".into();
                    }
                    NetworkEvent::DataReceived(data) => {
                        let received_str = String::from_utf8(data).unwrap_or_else(|e| {
                            e.into_bytes() // 拿回原始字节
                                .iter()
                                .map(|byte| format!("{byte:02x}",)) // 转换为两位小写十六进制
                                .collect::<String>()
                        });
                        if !received_str.is_empty() {
                            self.received_data = received_str.trim().to_owned();
                            self.logs = format!("✔ Reiceved message! at {}", util::now());
                        }
                    }
                    NetworkEvent::HttpResponse(result) => match result {
                        Ok(response) => {
                            self.response_http_status_code = response.status_code;
                            self.response_http_headers = response.headers;
                            self.response_http_body = response.body;
                            self.response_content_type = self
                                .response_http_headers
                                .iter()
                                .find(|(k, _)| k.eq_ignore_ascii_case("content-type"))
                                .map(|(_, v)| {
                                    if v.contains("application/json") {
                                        HttpResponseContentType::Json
                                    } else if v.contains("application/xml")
                                        || v.contains("text/xml")
                                    {
                                        HttpResponseContentType::Xml
                                    } else if v.contains("text/html") {
                                        HttpResponseContentType::Html
                                    } else {
                                        HttpResponseContentType::Text
                                    }
                                })
                                .unwrap_or(HttpResponseContentType::Text);

                            self.logs = format!(
                                "Success: Received {} status.",
                                self.response_http_status_code
                            );
                        }
                        Err(err_msg) => {
                            self.logs = format!("❌ HTTP Error: {err_msg}");
                        }
                    },
                    NetworkEvent::Error(err_msg) => {
                        self.connection_status = ConnectionStatus::Disconnected;
                        self.logs = format!("❌ Network Error: {err_msg}");
                    }
                    NetworkEvent::Disconnected => {
                        self.connection_status = ConnectionStatus::Disconnected;
                        self.logs = "Disconnected from server.".into();
                    }
                }
            }
        }
    }
}

impl ScrollTrait for App {
    fn scroll_down(&mut self) -> bool {
        if self.scroll_position < self.received_data.len().saturating_sub(1) {
            self.scroll_position = self.scroll_position.saturating_add(1);
            true
        } else {
            false
        }
    }

    fn scroll_up(&mut self) -> bool {
        // 只有在不是最顶部时才减少位置
        if self.scroll_position > 0 {
            self.scroll_position = self.scroll_position.saturating_sub(1);
            true
        } else {
            false
        }
    }
}

impl HttpMethod {
    pub fn next(&self) -> Self {
        match self {
            HttpMethod::Get => HttpMethod::Post,
            HttpMethod::Post => HttpMethod::Put,
            HttpMethod::Put => HttpMethod::Delete,
            HttpMethod::Delete => HttpMethod::Patch,
            HttpMethod::Patch => HttpMethod::Get,
        }
    }
}

impl Display for HttpMethod {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{self:?}",)
    }
}

impl fmt::Display for ProtocolType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            ProtocolType::Tcp => write!(f, "TCP"),
            ProtocolType::Udp => write!(f, "UDP"),
            ProtocolType::Http => write!(f, "HTTP"),
        }
    }
}

impl From<ProtocolType> for &str {
    fn from(value: ProtocolType) -> &'static str {
        match value {
            ProtocolType::Tcp => "TCP",
            ProtocolType::Udp => "UDP",
            ProtocolType::Http => "HTTP",
        }
    }
}

impl HttpRequestContentType {
    pub fn next(&self) -> Self {
        // 添加循环切换方法
        match self {
            Self::Json => Self::Xml,
            Self::Xml => Self::Text,
            Self::Text => Self::Html,
            Self::Html => Self::FormData,
            Self::FormData => Self::Raw,
            Self::Raw => Self::Json,
        }
    }
}
impl Display for HttpRequestContentType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{self:?}")
    }
}

impl AppMode {
    // 是否是编辑模式
    pub fn is_editing(&self) -> bool {
        matches!(
            self,
            AppMode::EditingData
                | AppMode::EditingAddress
                | AppMode::EditingHeaders
                | AppMode::EditingParams
                | AppMode::EditingBody
        )
    }

    // 是否是弹窗模式
    pub fn is_prompt(&self) -> bool {
        matches!(
            self,
            AppMode::ConfirmingHttpRequesting
                | AppMode::ConfirmingQuit
                | AppMode::ConfirmingSwitchProtocol
                | AppMode::ConfirmingClearScreen
                | AppMode::ConfirmingConnect
                | AppMode::ConfirmingSend
                | AppMode::ConfirmingDisconnect
        )
    }
}

impl PromptLevel {
    pub fn get_color(&self) -> Color {
        match self {
            PromptLevel::Normal => Color::Green,
            PromptLevel::Warning => Color::Yellow,
            PromptLevel::Error => Color::Red,
        }
    }
}
